﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using XcoAppSpaces.Core;
using System.Diagnostics;
using System.Threading;

namespace AlternativePorts.Tests
{
	[TestFixture]
	public class PortTests
	{
		Port<int> port;

		[SetUp]
		public void SetUp()
		{
			port = new Port<int>();
		}

		[Test]
		public void TestPost_NoReceiver()
		{
			port.Post(123);
			Assert.AreEqual(1, port.ItemCount);
		}

		[Test]
		public void TestPostUnknownType_NoReceiver()
		{
			port.PostUnknownType(123);
			Assert.AreEqual(1, port.ItemCount);
		}

		[Test]
		[ExpectedException(typeof(ArgumentException))]
		public void TestPostUnknownType_InvalidType()
		{
			port.PostUnknownType("invalid");
		}

		[Test]
		public void TestRegisterReceiver_Parallel_ThenPost()
		{
			int item = 0;
			port.RegisterReceiver(i => item = i, ReceiveMode.Parallel);
			port.Post(123);
			Thread.Sleep(100);
			Assert.AreEqual(123, item);
			Assert.AreEqual(0, port.ItemCount);
		}

		[Test]
		public void TestRegisterReceiver_Sequential_ThenPost()
		{
			int item = 0;
			port.RegisterReceiver(i => item = i, ReceiveMode.Sequential);
			port.Post(123);
			Thread.Sleep(100);
			Assert.AreEqual(123, item);
			Assert.AreEqual(0, port.ItemCount);
		}

		[Test]
		public void TestPost_ThenRegisterReceiver_Parallel()
		{
			int item = 0;
			port.Post(123);
			port.RegisterReceiver(i => item = i, ReceiveMode.Parallel);
			Thread.Sleep(100);
			Assert.AreEqual(123, item);
			Assert.AreEqual(0, port.ItemCount);
		}

		[Test]
		public void TestPost_ThenRegisterReceiver_Sequential()
		{
			int item = 0;
			port.Post(123);
			port.RegisterReceiver(i => item = i, ReceiveMode.Sequential);
			Thread.Sleep(100);
			Assert.AreEqual(123, item);
			Assert.AreEqual(0, port.ItemCount);
		}

		[Test]
		public void TestRegisterReceiverThatThrowsException()
		{
			port.RegisterReceiver(i => { throw new Exception(); }, ReceiveMode.Parallel);
			port.Post(123);
			port.Post(456);
			Thread.Sleep(100);
			Assert.AreEqual(0, port.ItemCount);
		}
	}
}
